package com.hhit.zhgd.service.impl

import cn.afterturn.easypoi.excel.ExcelExportUtil
import cn.afterturn.easypoi.excel.ExcelImportUtil
import cn.afterturn.easypoi.excel.entity.ExportParams
import cn.afterturn.easypoi.excel.entity.ImportParams
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult
import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.collection.CollUtil
import cn.hutool.core.map.MapUtil
import cn.hutool.core.util.ObjectUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.metadata.IPage
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.hhit.zhgd.config.InitDictionaryConfig
import com.hhit.zhgd.dao.ZhgdDrawingSupplyPlanMapper
import com.hhit.zhgd.domain.dto.BackStageDrawingSupplyPlanDTO
import com.hhit.zhgd.domain.entity.ZhgdDrawingSupplyPlan
import com.hhit.zhgd.domain.excelimport.DrawingSupplyPlanImportParam
import com.hhit.zhgd.domain.response.BaseResp
import com.hhit.zhgd.service.ZhgdDrawingSupplyPlanService
import com.hhit.zhgd.utils.CustomExcelExportStyler
import jakarta.servlet.http.HttpServletResponse
import org.springframework.beans.BeanUtils
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.multipart.MultipartFile
import java.net.URLEncoder
import java.util.HashMap

@Service("zhgdDrawingSupplyPlanService")
class ZhgdDrawingSupplyPlanServiceImpl : ZhgdDrawingSupplyPlanService,ServiceImpl<ZhgdDrawingSupplyPlanMapper, ZhgdDrawingSupplyPlan>() {

    @Transactional(rollbackFor = [Exception::class])
    override fun importDrawingSupplyPlan(multipartFile: MultipartFile?): BaseResp<Any?>? {
        remove(QueryWrapper())
        val params = ImportParams()
        // 表头设置为1行
        params.headRows = 1
        val result: ExcelImportResult<DrawingSupplyPlanImportParam?> =
            ExcelImportUtil.importExcelMore<DrawingSupplyPlanImportParam>(
                multipartFile!!.inputStream,
                DrawingSupplyPlanImportParam::class.java, params
            )
        if (CollUtil.isNotEmpty(result.failList)) {
            for (drawingSupplyPlanImportParam in result.failList) {
                val msg =
                    "第" + ((drawingSupplyPlanImportParam?.getRowNum()?:0) + 1) + "行的错误是：" + drawingSupplyPlanImportParam?.errorMsg
                return BaseResp.fail("导入失败:$msg")
            }
        }
        val zhgdDrawingSupplyPlans: MutableList<ZhgdDrawingSupplyPlan> = CollUtil.newArrayList()
        for (drawingSupplyPlanImportParam in result.list) {
            val zhgdDrawingSupplyPlan = ZhgdDrawingSupplyPlan()
            BeanUtil.copyProperties(drawingSupplyPlanImportParam, zhgdDrawingSupplyPlan)
            zhgdDrawingSupplyPlan.deliveryTime =drawingSupplyPlanImportParam?.deliveryTime
            zhgdDrawingSupplyPlans.add(zhgdDrawingSupplyPlan)
        }
        val saveBatchRes = this.saveBatch(zhgdDrawingSupplyPlans)
        return if (saveBatchRes) {
            BaseResp.success()
        } else {
            BaseResp.fail("导入图纸供应计划数据失败!")
        }
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun confirmHandInDrawings(id: Int?): BaseResp<Any?>? {
        val zhgdDrawingSupplyPlan = getById(id)
        zhgdDrawingSupplyPlan.handInDrawingsFlag=1
        val updateRes = updateById(zhgdDrawingSupplyPlan)
        return if (updateRes) {
            BaseResp.success()
        } else {
            BaseResp.fail("修改交图状态失败")
        }
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun addDrawing(backStageDrawingSupplyPlanDTO: BackStageDrawingSupplyPlanDTO?): BaseResp<Any?>? {
        val drawingSupplyPlan = this.getOne(
            QueryWrapper<ZhgdDrawingSupplyPlan>().eq(
                "volume_number",
                backStageDrawingSupplyPlanDTO?.volumeNumber
            ).last("limit 1")
        )
        if (ObjectUtil.isNotNull(drawingSupplyPlan)) {
            return BaseResp.fail("该卷册编号已存在!添加失败!")
        }
        val zhgdDrawingSupplyPlan = ZhgdDrawingSupplyPlan()
        BeanUtil.copyProperties(backStageDrawingSupplyPlanDTO, zhgdDrawingSupplyPlan)
        val addRes = save(zhgdDrawingSupplyPlan)
        return if (addRes) {
            BaseResp.success()
        } else BaseResp.fail("添加图纸供应计划失败!")
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun editDrawing(backStageDrawingSupplyPlanDTO: BackStageDrawingSupplyPlanDTO?): BaseResp<Any?>? {
        val (_, _, _, volumeNumber) = getById(backStageDrawingSupplyPlanDTO?.id)
        if (volumeNumber != backStageDrawingSupplyPlanDTO?.volumeNumber) {
            val drawingSupplyPlan = this.getOne(
                QueryWrapper<ZhgdDrawingSupplyPlan>().eq(
                    "volume_number",
                    backStageDrawingSupplyPlanDTO?.volumeNumber
                ).last("limit 1")
            )
            if (ObjectUtil.isNotNull(drawingSupplyPlan)) {
                return BaseResp.fail("该卷册编号已存在!修改失败!")
            }
        }
        val zhgdDrawingSupplyPlan = ZhgdDrawingSupplyPlan()
        BeanUtil.copyProperties(backStageDrawingSupplyPlanDTO, zhgdDrawingSupplyPlan)
        val editRes = updateById(zhgdDrawingSupplyPlan)
        return if (editRes) {
            BaseResp.success()
        } else BaseResp.fail("修改图纸供应计划失败!")
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun delDrawing(ids: List<Int?>?): BaseResp<Any?>? {
        val delRes = this.removeByIds(ids)
        return if (delRes) {
            BaseResp.success()
        } else BaseResp.fail("删除图纸供应计划失败!")
    }

    override fun getDrawingPageInfo(keyWord: String?, page: Int?, size: Int?): IPage<BackStageDrawingSupplyPlanDTO>? {
        val queryWrapper = QueryWrapper<ZhgdDrawingSupplyPlan>()
        if (StrUtil.isNotBlank(keyWord)) {
            queryWrapper.like("stage", keyWord)
                .or().like("volume_number", keyWord)
                .or().like("volume_name", keyWord)
                .or().like("volume_classify", keyWord)
                .or().like("delivery_time", keyWord)
                .or().like("handIn_drawings_flag", keyWord)
        }
        val pageRequest = Page<ZhgdDrawingSupplyPlan>(
            page!!.toLong(), size!!.toLong()
        )
        val zhgdDrawingSupplyPlanPage: IPage<ZhgdDrawingSupplyPlan> = this.page(pageRequest, queryWrapper)
        // Convert to DTO
        val dtoList = zhgdDrawingSupplyPlanPage.records
            .map { entity: ZhgdDrawingSupplyPlan ->
                val dto = BackStageDrawingSupplyPlanDTO()
                BeanUtils.copyProperties(entity, dto)
                dto.handInDrawingsFlagName=MapUtil.getStr(
                    InitDictionaryConfig.DICTIONARY_MAP,
                    String.format("%s/%s", InitDictionaryConfig.HAND_IN_DRAWINGS_FLAG, entity.handInDrawingsFlag),
                    StrUtil.EMPTY
                )
                dto
            }.toCollection(ArrayList())
        val dtoPage: IPage<BackStageDrawingSupplyPlanDTO> = Page(
            page!!.toLong(), size!!.toLong(), zhgdDrawingSupplyPlanPage.total
        )
        dtoPage.records = dtoList
        return dtoPage
    }

    override fun exportDrawingPlan(response: HttpServletResponse?) {
        val backStageDrawingSupplyPlanDTOS: MutableList<BackStageDrawingSupplyPlanDTO> = java.util.ArrayList()
        val zhgdDrawingSupplyPlans = this.list()
        for (zhgdDrawingSupplyPlan in zhgdDrawingSupplyPlans) {
            val backStageDrawingSupplyPlanDTO = BackStageDrawingSupplyPlanDTO()
            BeanUtils.copyProperties(zhgdDrawingSupplyPlan, backStageDrawingSupplyPlanDTO)
            backStageDrawingSupplyPlanDTO.handInDrawingsFlagName = MapUtil.getStr(
                InitDictionaryConfig.DICTIONARY_MAP,
                String.format(
                    "%s/%s",
                    InitDictionaryConfig.HAND_IN_DRAWINGS_FLAG,
                    zhgdDrawingSupplyPlan.handInDrawingsFlag
                ),
                StrUtil.EMPTY
            )
            backStageDrawingSupplyPlanDTOS.add(backStageDrawingSupplyPlanDTO)
        }
        // 设计表头格式
        val drawingPlanTableHeaderList: List<ExcelExportEntity>? = getExportRebateOffsetTableHeader()
        // 根据表头对应的key填充数据
        val drawingPlanRecordList: List<Map<String, Any?>>? =
            getExportRebateOffsetCallRecord(backStageDrawingSupplyPlanDTOS)

        val exportParams = ExportParams(null, "")
        exportParams.type = ExcelType.HSSF
        exportParams.style = CustomExcelExportStyler::class.java
        // 根据表头和数据导出Excel
        val workbook = ExcelExportUtil.exportExcel(exportParams, drawingPlanTableHeaderList, drawingPlanRecordList)

        response?.characterEncoding = "UTF-8"
        response?.contentType = "application/vnd.ms-excel"
        response?.setHeader(
            "Content-disposition",
            "attachment;filename=" + URLEncoder.encode(
                String.format("%s_%s.xls", "图纸供应计划", System.currentTimeMillis()),
                "UTF-8"
            )
        )
        workbook.write(response?.outputStream)
        workbook.close()
    }


    private fun getExportRebateOffsetTableHeader(): List<ExcelExportEntity>? {
        // 表头设置
        val drawingPlanTableHeaderList: MutableList<ExcelExportEntity> = java.util.ArrayList()
        val sortEntity = ExcelExportEntity("序号", "sort")
        //        planStartEntity.setMergeVertical(true);
        drawingPlanTableHeaderList.add(sortEntity)
        val stageEntity = ExcelExportEntity("阶段", "stage")
        //        planCompleteEntity.setMergeVertical(true);
        drawingPlanTableHeaderList.add(stageEntity)
        val volumeNumberEntity = ExcelExportEntity("卷册编号", "volumeNumber")
        //        plannedTimeEntity.setMergeVertical(true);
        drawingPlanTableHeaderList.add(volumeNumberEntity)
        val volumeNameEntity = ExcelExportEntity("实际时间", "volumeName")
        //        actualStartEntity.setMergeVertical(true);
        drawingPlanTableHeaderList.add(volumeNameEntity)
        val volumeClassifyEntity = ExcelExportEntity("卷册分类", "volumeClassify")
        //        actualStartEntity.setMergeVertical(true);
        drawingPlanTableHeaderList.add(volumeClassifyEntity)
        val deliveryTimeEntity = ExcelExportEntity("交付时间", "deliveryTime")
        //        actualStartEntity.setMergeVertical(true);
        drawingPlanTableHeaderList.add(deliveryTimeEntity)
        //        statusEntity.setMergeVertical(true);
        return drawingPlanTableHeaderList
    }

    private fun getExportRebateOffsetCallRecord(list: List<BackStageDrawingSupplyPlanDTO>): List<Map<String, Any?>>? {
        val drawingSupplyRecordList: MutableList<Map<String, Any?>> = java.util.ArrayList()
        for (i in list.indices) {
            val drawingSupplyRecordMap: MutableMap<String, Any?> = HashMap()
            drawingSupplyRecordMap["sort"] = i + 1
            drawingSupplyRecordMap["stage"] = list[i].stage
            drawingSupplyRecordMap["volumeNumber"] = list[i].volumeNumber
            drawingSupplyRecordMap["volumeName"] = list[i].volumeName
            drawingSupplyRecordMap["volumeClassify"] = list[i].volumeClassify
            drawingSupplyRecordMap["deliveryTime"] = list[i].deliveryTime
            drawingSupplyRecordList.add(drawingSupplyRecordMap)
        }
        return drawingSupplyRecordList
    }
}